<template>
  <div class="search">
    <!-- 搜索框部分 -->
    <van-search
      v-model="searchText"
      placeholder="请输入搜索关键词"
      show-action
      shape="round"
      @input="onSearchInput"
    >
    <!-- 搜索按钮 -->
      <div slot="action" @click="onSearch(searchText)">搜索</div>
    </van-search>
    <!-- 联想建议 -->
    <van-cell-group v-show="searchText">
      <van-cell
        icon="search"
        v-for="item in suggestions"
        :key="item"
        @click="onSearch(item)"
      >
      <!-- 点击联想项后跳转到搜索页面 可以使用搜索按钮相同的事件 传相应的参数即可 -->
        <div slot="title" v-html="highlight(item)"></div>
      </van-cell>
    </van-cell-group>
    <!-- /联想建议 -->
    <!-- 历史记录 -->
    <van-cell-group v-show="!searchText">
      <van-cell
        title="历史记录"
      >
      <div v-show="isDeleteShow">
        <!--点击全部删除 首先想到的是删除本地存储 而这里用到的是更直接的操作数组
            通过watch监听 将数组searchHistories变为[]后 空数组 遍历后不做页面渲染
            watch就会把这个[]保存起来 相应的历史记录获取本地存储时就为[]了 实现数据持久化
            vue是数据驱动视图 视图响应数据 首先想到改变数据来推动视图变化的思想-->
          <span @click="searchHistories = []">全部删除</span>&nbsp;&nbsp;
          <span @click="isDeleteShow = false">完成</span>
        </div>
        <van-icon
          v-show="!isDeleteShow"
          name="delete"
          @click="isDeleteShow = true"
        />
      </van-cell>
      <van-cell
        v-for="(item, index) in searchHistories"
        :key="item"
        :title="item"
      >
        <van-icon
          v-show="isDeleteShow"
          name="close"
          @click.stop="searchHistories.splice(index, 1)"
        />
        <!-- 点击事件 会冒泡触发跳转搜索结果 所以应阻止冒泡
             而且这里用到的是修改数组数据 watch监听该数组的动态变化
             只对这个数组操作即可  -->
      </van-cell>
    </van-cell-group>
  </div>
</template>

<script>
import { getSuggestions } from '@/api/search'
import { setItem, getItem } from '@/utils/storage'
// 引入工具库lodash中的防抖功能 debounce(fn, 500) 500毫秒内只调用一次时才触发函数
// 内部清除之前定时器后再注册新的定时器 500时间内一直重复操作一直不触发 因为一直在清除之前的定时器
// 此处还可以用节流 throttle(fn, 500) 即为定时每500触发函数fn
// 用法和debounce相同
import { debounce } from 'lodash'

export default {
  name: 'search',
  data () {
    return {
      searchText: '',
      suggestions: [],
      isDeleteShow: false,
      searchHistories: getItem('search-histories') || []
      // 获取本地存储 本地也可能没有数据 此时为[]
    }
  },
  watch: {
    searchHistories () {
      setItem('search-histories', this.searchHistories)
    }
  },
  computed: {
  },
  methods: {
    onSearch (q) {
      // 做非空判断
      if (!q.trim()) {
        return
      }
      // 我们要判断 这个参数是否已经在searchHistories的数组中
      // 如果已经在数组中 清除掉数组中该相同项 并将这个项添加到数组最前面 表示最新浏览过
      // 的历史记录
      // indexOf判断q是否已存在 存在返回索引 不存在返回-1
      const index = this.searchHistories.indexOf(q)
      // 如果存在则 index不为-1
      if (index !== -1) {
        // 此时删除数组中这一项
        this.searchHistories.splice(index, 1)
      }
      // 再将这个q添加到数组最前面 用unshift()
      this.searchHistories.unshift(q)
      // 添加完后 保存这个数组
      // 这里需要注意 watch里监视了searchHistories这个数组 但是这里不能省略保存这一步
      // 因为这里不保存 会向下执行跳转页面 watch无法监听立即跳转到别的页面的searchHistories的变化
      setItem('search-histories', this.searchHistories)
      // 先保存 再跳转 不会错过这个历史记录
      this.$router.push(`/search/${q}`)
    },
    // lodash 是一个高性能js工具库 只用其中的防抖功能debounce 单独引入即可
    // 我们要实现防抖功能 在请求搜索联想的函数上使用debounce 即可实现
    // 函数简写 debounce是不支持的 要写函数完整形式 异步async要直接加在使用await的函数前
    // 不可以是嵌套或其他方式 debuonce(防抖函数, 防抖时间间隔)
    onSearchInput: debounce(async function () {
      const suggestions = this.searchText.trim()
      if (!suggestions) {
        return
      }
      const res = await getSuggestions(this.searchText)
      this.suggestions = res.data.data.options
    }, 500),
    // async onSearchInput () {
    //   const suggestions = this.searchText.trim()
    //   if (!suggestions) {
    //     return
    //   }
    //   const res = await getSuggestions(this.searchText)
    //   this.suggestions = res.data.data.options
    // },
    highlight (item) {
      // 这个方法首先将搜索的参数高亮 是一个变化的数据 而正则表达式/这里都是字符串/
      // 我们要创建一个动态的正则表达式,使用new RegExp 手动构建
      // 将input框写入的内容当参数1 参数2写匹配模式 g是全局 i是忽略大小写
      const reg = new RegExp(this.searchText, 'ig')
      // replace方法 替换符合条件的内容 将符合reg这个动态正则表达式的
      // 修改为内容为红色的input框输入内容
      return item.replace(reg, `<span style="color: red">${this.searchText}</span>`)
    }
  }
}
</script>

<style>

</style>
